package com.xing.photo.funcation;

import com.xing.photo.bean.PhotoUser;
import com.xing.photo.dao.UserDao;
import com.xing.photo.util.StaticUtil;
import com.xing.photo.util.VarConfig;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: xingzhe
 * Date: 2015/3/2
 * Time: 13:31
 */
public class Begin {
    private static final ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
    VarConfig config = (VarConfig) ac.getBean("config");
    UserDao userDao = (UserDao) ac.getBean("userDao");
    private static Logger photoJson = LoggerFactory.getLogger("photoJson");

    public static void main(String[] args) {
        Begin begin = new Begin();
        try {
            begin.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void start() throws IOException {
        List<PhotoUser> list = userDao.listUsers(51);
        if (list != null && list.size() > 0) {
            for (PhotoUser user : list) {
                String content = getContent(getUri(user, config.getPageBegin()));
                ObjectMapper mapper = new ObjectMapper();
                JsonNode resultNode = mapper.readTree(content);
                int total = resultNode.get("data").get("total").asInt();
                if (user.getTotal() == 0) {
                    System.out.println("一个新的用户，全批量下载: " + user.getName());
                    batchImg(user, total);
                } else if (user.getTotal() != total) {
                    System.out.println("需要增量更新: " + user.getName());
                    incrementalImg(user, total);
                } else {
                    System.out.println("这个骚货没有更新相册: " + user.getName());
                }
            }
        }
    }

    private void incrementalImg(PhotoUser user, int total) throws IOException {
        if (total > user.getTotal()) {
            int incr = total - user.getTotal();
            String content = getContent(getUri(user, config.getPageBegin()));
            photoJson.info(content);
            ObjectMapper mapper = new ObjectMapper();
            JsonNode resultNode = mapper.readTree(content);
            JsonNode dataNode = resultNode.get("data").get("photo_list");
            if (dataNode == null || dataNode.size() < 1) {
                int result = userDao.delUser(user);
                if (result > 0) {
                    System.out.println("这个用户删除了所有微博和相册: " + user.getName());
                }
            } else {
                if (incr <= config.getCount()) {
                    for (int i = 0; i < incr; i++) {
                        System.out.println("http://ww3.sinaimg.cn/large/" + dataNode.get(i).get("pic_name").asText());
                        saveImg("http://ww3.sinaimg.cn/large/" + dataNode.get(i).get("pic_name").asText(), dataNode.get(i).get("pic_name").asText(), user.getName());
                    }
                } else {
                    batchImg(user, incr);
                }
            }
        } else {
            System.out.println("there is something error!" + " database total: " + user.getTotal() + " user total: " + total);
        }
        user.setTotal(total);
        int result = userDao.updateUser(user);
        if (result > 0) {
            System.out.println("增量更新完毕");
        }
    }

    private void batchImg(PhotoUser user, int total) throws IOException {
        int pageCount = total / config.getCount() + 2;
        for (int i = 1; i < pageCount; i++) {
            URI uri = getUri(user, i);
            String content = getContent(uri);
            ObjectMapper mapper = new ObjectMapper();
            JsonNode resultNode = mapper.readTree(content);
            JsonNode dataNode = resultNode.get("data").get("photo_list");
            if (dataNode != null) {
                for (int j = 0; j < dataNode.size(); j++) {
                    System.out.println("http://ww3.sinaimg.cn/large/" + dataNode.get(j).get("pic_name").asText());
                    saveImg("http://ww3.sinaimg.cn/large/" + dataNode.get(j).get("pic_name").asText(), dataNode.get(j).get("pic_name").asText(), user.getName());
                }
            }
        }
        user.setTotal(total);
        int result = userDao.updateUser(user);
        if (result > 0) {
            System.out.println("批量下载完毕，爽! ");
        }
    }

    private static void saveImg(String img, String picName, String userName) {
        InputStream is = null;
        OutputStream os = null;
        URL url;
        HttpURLConnection con;
        File file = new File("E:/weibo_photo/" + userName + "/");
        if (!file.exists()) {
            if (file.mkdir()) {
                System.out.println("创建新文件夹: " + userName);
            }
        }
        try {
            url = new URL(img);
            con = (HttpURLConnection) url.openConnection();
            // 设置连接超时
            con.setConnectTimeout(100 * 1000);
            // 设置读取超时
            con.setReadTimeout(100 * 1000);
            is = new BufferedInputStream(con.getInputStream());
            os = new BufferedOutputStream(new FileOutputStream(new File("E:/weibo_photo/" + userName + "/" + picName)));
            byte[] b = new byte[1024];
            int length;
            while ((length = is.read(b)) != -1) {
                os.write(b, 0, length);
            }
            os.flush();
            con.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private URI getUri(PhotoUser user, int pageBegin) {
        URI uri = null;
        try {
            uri = new URIBuilder().setScheme(config.getUriScheme()).setHost(config.getHost()).setPath(config.getPath())
                    .setParameter("uid", user.getUid() + "")
                    .setParameter("album_id", user.getAlbumId() + "")
                    .setParameter("count", config.getCount() + "")
                    .setParameter("page", pageBegin + "")
                    .setParameter("type", config.getType() + "").build();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return uri;
    }

    private String getContent(URI uri) {
        String result = null;
        try {
            HttpGet httpGet = new HttpGet(uri);
            httpGet.setHeader("Cookie", StaticUtil.cookies);
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            CloseableHttpResponse response = httpClient.execute(httpGet);
            HttpEntity re = response.getEntity();
            result = EntityUtils.toString(re, config.getCharset());
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
}
